home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / smailsrc.zip / UUPC.ZIP / ULIB.C < prev    next >
Text File  |  1990-04-21  |  10KB  |  452 lines

  1. /*
  2.     For best results in visual layout while viewing this file, set
  3.     tab stops to every 8 columns.
  4. */
  5.  
  6. /*
  7.     ibmpc/ulib.c
  8.  
  9.     DCP system-dependent library
  10.  
  11.     Services provided by ulib.c:
  12.  
  13.     - login
  14.     - UNIX commands simulation
  15.     - serial I/O
  16.     - rnews
  17. */
  18.  
  19. /*
  20.  *      Modified by Stephen C. Trier (sct@po.CWRU.Edu)
  21.  *      January - April, 1990
  22.  *
  23.  *      Added support for external rmail and rnews commands.
  24.  *      External rmail is mandatory; external rnews is not.
  25.  *
  26.  *      DTR now stays low long enough to make smart modem hang
  27.  *      up.  This was needed for multiple-host support.
  28.  */
  29.  
  30. #include <stdio.h>
  31. #include <string.h>
  32. #include <process.h>
  33. #include <fcntl.h>
  34.  
  35. #include "dcp.h"
  36.  
  37. extern int rmsg();
  38. extern void wmsg();
  39.  
  40. /*
  41.     login - login handler
  42. */
  43.  
  44. /* Currently a dumb login handler for PC in slave mode. */
  45.  
  46. char login(void)
  47. {
  48.     char line[132];
  49.  
  50.     for ( ; ; ) {
  51.  
  52.         msgtime = 9999; /* make it very long */
  53.         while (rmsg(line, 0) == -1);    /* wait for a <CR> or <NL> */
  54.         msgtime = 2 * MSGTIME;
  55.  
  56.         wmsg("Login:", 0);
  57.         if (rmsg(line, 0) == -1)
  58.             continue;
  59.         printmsg(0, "login: login=%s", line);
  60.  
  61.         wmsg("Password:", 0);
  62.         if (rmsg(line, 0) == -1)
  63.             continue;
  64.         printmsg(14, "login: password=%s", line);
  65.  
  66.         if (equal(line, "uucp"))
  67.             break;
  68.  
  69.     }
  70.     printmsg(14, "login: logged in");
  71.  
  72.     return 'I';
  73.  
  74. } /*login*/
  75.  
  76.  
  77. /*
  78.     notimp - "perform" Unix commands which aren't implemented
  79. */
  80.  
  81. static int notimp(argc, argv)
  82. int argc;
  83. char *argv[];
  84. {
  85.     int i = 1;
  86.  
  87.     printmsg(0, "shell: command '%s' not implemented", *argv);
  88.     while (i < argc)
  89.         printmsg(6, "shell: argv[%d]=\"%s\"", i++, *argv++);
  90.  
  91.     return 0;
  92.  
  93. } /*notimp*/
  94.  
  95.  
  96. /*
  97.     shell - simulate a Unix command
  98.  
  99.     Only the 'rmail' and 'rnews' command are currently supported.
  100. */
  101.  
  102. void shell(command, inname, outname, errname)
  103. char *command;
  104. char *inname, *outname, *errname;
  105. {
  106.     extern int rmail(), rnews();
  107.  
  108.     char *argv[50];
  109.     int argc;
  110.     int (*proto)();
  111.  
  112.     argc = getargs(command, argv);
  113.  
  114.     if (debuglevel >= 6) {
  115.         char **argvp = argv;
  116.         int i = 0;
  117.         while (i < argc)
  118.             printmsg(6, "shell: argv[%d]=\"%s\"", i++, *argvp++);
  119.     }
  120.  
  121.     if (equal(argv[0], "rmail"))
  122.         proto = rmail;
  123.     else if (equal(argv[0], "rnews"))
  124.         proto = rnews;
  125.     else
  126.         proto = notimp;
  127.  
  128.     if (*inname != '\0') {
  129.         char localname[64];
  130.         importpath(localname, inname);
  131.         if (freopen(localname, "rb", stdin) == nil(FILE)) {
  132.             extern int errno;
  133.             printmsg(0, "shell: couldn't open %s (%s), errno=%d.",
  134.                 inname, localname, errno);
  135.         }
  136.     }
  137.  
  138.     (*proto)(argc, argv);
  139.  
  140.     freopen("con", "r", stdin);
  141.  
  142. } /*shell*/
  143.  
  144.  
  145. /* IBM-PC I/O routines */
  146.  
  147. /* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */
  148.  
  149. /*************** BASIC I/O ***************************/
  150. /* Saltzers serial package (aka Info-IBMPC COM_PKG2):
  151.  * Some notes:  When packets are flying in both directions, there seems to
  152.  * be some interrupt handling problems as far as receiving.  Checksum errors
  153.  * may therefore occur often even though we recover from them.  This is
  154.  * especially true with sliding windows.  Errors are very few in the VMS
  155.  * version.  RH Lamb
  156.  */
  157.  
  158. #include "comm\comm.h"
  159.  
  160. #define STOPBIT 1
  161. #define LINELOG "LineData.Log"      /* log serial line data here */
  162.  
  163. static int log_handle;
  164. static FILE *log_stream;
  165.  
  166. /*
  167.     openline - open the serial port for I/O
  168. */
  169.  
  170. int openline(name, baud)
  171. char *name, *baud;
  172. {
  173.     int value;
  174.  
  175.     printmsg(15, "openline: %s, %s", name, baud);
  176.  
  177.     sscanf(name, "COM%d", &value);
  178.     select_port(value);
  179.     save_com();
  180.     install_com();
  181.     open_com(atoi(baud), 'D', 'N', STOPBIT, 'D');
  182.     dtr_on();
  183.  
  184.     /* log serial line data only if log file already exists */
  185.     log_handle = open(LINELOG, O_WRONLY | O_TRUNC | O_BINARY);
  186.     if (log_handle != -1) {
  187.         printmsg(15, "logging serial line data to %s", LINELOG);
  188.         log_stream = fdopen(log_handle, "wb");
  189.     }
  190.  
  191.     return 0;
  192.  
  193. } /*openline*/
  194.  
  195.  
  196. /*
  197.     sread - read from the serial port
  198. */
  199.  
  200. /*  Non-blocking read essential to "g" protocol.
  201.     See "dcpgpkt.c" for description.
  202.     This all changes in a multi-tasking system.  Requests for
  203.     I/O should get queued and an event flag given.  Then the
  204.     requesting process (e.g. gmachine()) waits for the event
  205.     flag to fire processing either a read or a write.
  206.     Could be implemented on VAX/VMS or DG but not MS-DOS. */
  207.  
  208. int sread(buffer, wanted, timeout)
  209. char *buffer;
  210. int wanted, timeout;
  211. {
  212.     long start;
  213.  
  214.     start = time(nil(long));
  215.     for ( ; ; ) {
  216.         int pending;
  217.         pending = r_count_pending();
  218.         printmsg(20, "sread: pending=%d, wanted=%d", pending, wanted);
  219.         if (pending >= wanted) {    /* got enough in the buffer? */
  220.             int i;
  221.             for (i = 0; i < wanted; i++)
  222.                 *buffer++ = receive_com();
  223.             if (log_handle != -1) {
  224.                 buffer -= wanted;
  225.                 for (i = 0; i < wanted; i++) {
  226.                     fputc(0x01, log_stream);    /* 1 for writes */
  227.                     fputc(*buffer++, log_stream);
  228.                 }
  229.             }
  230.             return pending;
  231.         } else {
  232.             int elapsed;
  233.             elapsed = time(nil(long)) - start;
  234.             if (elapsed >= timeout)
  235.                 return pending;
  236.       }
  237.    }
  238.  
  239. } /*sread*/
  240.  
  241.  
  242. /*
  243.     swrite - write to the serial port
  244. */
  245.  
  246. int swrite(data, len)
  247. char *data;
  248. int len;
  249. {
  250.     int i;
  251.  
  252.     for (i = 0; i < len; i++)
  253.         send_com(*data++);
  254.  
  255.     if (log_handle != -1) {
  256.         data -= len;
  257.         for (i = 0; i < len; i++) {
  258.             fputc(0x02, log_stream);    /* 2 for writes */
  259.             fputc(*data++, log_stream);
  260.         }
  261.     }
  262.  
  263.     return len;
  264.  
  265. } /*swrite*/
  266.  
  267.  
  268. /*
  269.     ssendbrk - send a break signal out the serial port
  270. */
  271.  
  272. void ssendbrk(duration)
  273. int duration;
  274. {
  275.  
  276.     printmsg(12, "ssendbrk: %d", duration);
  277.  
  278.     break_com();
  279.  
  280. } /*ssendbrk*/
  281.  
  282.  
  283. /*
  284.     closeline - close the serial port down
  285. */
  286.  
  287. void closeline(void)
  288. {
  289.     int far *stats;
  290.  
  291.     dtr_off();
  292.     close_com();
  293.     restore_com();
  294.     sleep(3);                       /* Make sure modem hangs up [SCT] */
  295.  
  296.     if (log_handle != -1) {     /* close serial line log file */
  297.         fclose(log_stream);
  298.         close(log_handle);
  299.     };
  300.  
  301.     stats = com_errors();
  302.     printmsg(3, "\nBuffer overflows: %d", stats[COM_EOVFLOW]);
  303.     printmsg(3, "Receive overruns: %d", stats[COM_EOVRUN]);
  304.     printmsg(3, "Break chars: %d", stats[COM_EBREAK]);
  305.     printmsg(3, "Framing errors: %d", stats[COM_EFRAME]);
  306.     printmsg(3, "Parity errors: %d", stats[COM_EPARITY]);
  307.     printmsg(3, "Transmit errors: %d", stats[COM_EXMIT]);
  308.     printmsg(3, "DSR errors: %d", stats[COM_EDSR]);
  309.     printmsg(3, "CTS errors: %d\n", stats[COM_ECTS]);
  310.  
  311. } /*closeline*/
  312.  
  313.  
  314. #ifndef __TURBOC__
  315. /*
  316.     sleep() - wait n seconds
  317.  
  318.     Simply delay until n seconds have passed.
  319. */
  320.  
  321. void sleep(interval)
  322. int interval;
  323. {
  324.     long start;
  325.  
  326.     start = time(nil(long));
  327.     while ((time(nil(long)) - start) < interval);
  328.  
  329. } /*sleep*/
  330. #endif /*__TURBOC__*/
  331.  
  332.  
  333. /*
  334.     SIOSpeed - re-specify the speed of an opened serial port
  335. */
  336.  
  337. void SIOSpeed(baud)
  338. char *baud;
  339. {
  340.  
  341.     dtr_off();
  342.     close_com();
  343.     open_com(atoi(baud), 'D', 'N', STOPBIT, 'D');
  344.     dtr_on();
  345.  
  346. } /*SIOSpeed*/
  347.  
  348.  
  349. /*
  350.  *  rnews - receive incoming news
  351.  *
  352.  *  I added provisions for a stand-alone rnews, with fallback to the normal
  353.  *  UUPC rnews.  I do not receive news, so I have not been able to test this
  354.  *  feature.  I hope it works.  If you try it, please send me a note saying
  355.  *  how it works.  -- Stephen Trier  (sct@po.cwru.edu)
  356.  *
  357.  *  rnews uses a static variable to tell it if any previous spawn of rnews
  358.  *  failed.  If it did, it will use the internal rnews.  This keeps the
  359.  *  routine from trying to spawn rnews for every single incoming news article,
  360.  *  unless there is an rnews there to receive them.  -- Stephen Trier
  361.  */
  362.  
  363. int rnews(int argc, char *argv[]) /* SCT */
  364. {
  365.     static int temp = 0;
  366.  
  367.     argv[argc] = NULL;
  368.  
  369.     if (temp != -1)
  370.     temp = spawnvp(P_WAIT, "rnews", argv);
  371.     switch (temp)  {
  372.     case 0:
  373.         break;
  374.     case -1:
  375.         printmsg(2, "Can't find rnews in path.  Using internal rnews.");
  376.         temp = old_rnews(argc, argv);
  377.         break;
  378.     default:
  379.         printmsg(1, "rnews returns %d", temp);
  380.         break;
  381.     }
  382.  
  383.     return temp;
  384. }
  385.  
  386. /*
  387.  * This is the original UUPC rnews, modified so that it handles
  388.  * binary data correctly. -- SCT
  389.  */
  390. int old_rnews(argc, argv)
  391. int argc;
  392. char *argv[];
  393. {
  394.     static int count = 1;
  395.     char filename[132], format[128], buf[BUFSIZ];
  396. #ifndef OLD_RNEWS
  397.     size_t charsread;
  398. #endif
  399.     FILE *f;
  400.     long now = time(nil(long));
  401.  
  402.     mkfilename(format, newsdir, "%08.8lX.%03.3d");  /* make pattern first */
  403.     sprintf(filename, format, now, count++);    /* build real file name */
  404.  
  405.     printmsg(6, "rnews: putting incoming news into %s", filename);
  406.     if ((f = FOPEN(filename, "w", BINARY)) == nil(FILE)) {
  407.     printmsg(0, "rnews: can't open %s (%d)", filename, errno);
  408.         return -1;
  409.     }
  410.  
  411. #ifdef OLD_RNEWS
  412.     while (fgets(buf, BUFSIZ, stdin) != nil(char))
  413.     fputs(buf, f);
  414. #else
  415.     while ((charsread = fread(buf, (size_t) 1, (size_t) BUFSIZ, stdin)) != 0)
  416.     fwrite(buf, (size_t) 1, charsread, f);
  417. #endif
  418.  
  419.     fclose(f);
  420.  
  421.     return 0;
  422.  
  423. } /*rnews*/
  424.  
  425.  
  426. /*
  427.  *      rmail - Call external rmail program  (SCT)
  428.  */
  429.  
  430. #include <errno.h>
  431.  
  432. int rmail(int argc, char *argv[])
  433. {
  434.     int temp;
  435.  
  436.     argv[argc] = NULL;
  437.  
  438.     temp = spawnvp(P_WAIT, "rmail", argv);
  439.     switch (temp)  {
  440.     case 0:
  441.         break;
  442.     case -1:
  443.         printmsg(0, "Error while forking rmail: %s", sys_errlist[errno]);
  444.         break;
  445.     default:
  446.         printmsg(1, "rmail returns %d", temp);
  447.         break;
  448.     }
  449.  
  450.     return temp;
  451. }
  452.